/** accinfo主程序文件
 * @file accinfo.cpp
 * @author Kiven Lee
 * @version 1.0
 * @date 2022-07-07
 *
 * @copyright Kivensoft (c) 2018 - 2022
 *
 */

#include "klib/ansi_color.hpp"
#include "klib/log.hpp"
#include "klib/file.hpp"
#include "klib_http/server.hpp"

#include <asio/co_spawn.hpp>
#include <asio/detached.hpp>

#include "app.hpp"
#include "api.hpp"
#include "session_data.hpp"

using namespace ai;
using namespace klib;
using namespace klib::http;

int main(int argc, char* argv[]) {
    // windows平台启用控制台utf8编码和ansi彩色支持
    ansic::utf8_term_t ut; (void)ut;

    // 处理命令行参数
    if (!app::parse(argc, argv)) return 0;

    app::show_logo();
    LOG_INFO(AC_G("{} startup"), app::name);

    // 初始化io上下文
    io_ctx_t io_ctx(1);

    // session data初始化，key的过期时间设置为jwt过期时间+3分钟，避免session比jwt更早的无效
    ai_session_manager_t sess_man(app::jwt_exp_minutes(), global_session_id_manager);

    io_ctx.set_interval(5 * 60000, [&sess_man] () { sess_man.gc(); });

    // 设置http服务的标识、静态文件根路径和api接口映射
    server_t http_server(io_ctx);
    app::set_server_name(http_server)
        .set_session_id_manager(global_session_id_manager)
        .set_webroot(path_t(app::work(), app::webroot))
        .set_api_prefix(app::api_prefix)
        .set_hook(pre_handler)
        .set_api_handlers(api_handlers, length_of(api_handlers));

    // 初始化全局对象
    app::init(io_ctx, http_server, sess_man);

    // 启动http服务监听
    try {
        asio::co_spawn(io_ctx, http_server.start(app::listen()), asio::detached);
    } catch (std::exception& e) {
        LOG_ERROR("http-server[" LC_R "] exception: " LC_R, app::listen(), e.what());
        return -1;
    }

    // 进入消息循环处理模式
    io_ctx.run();

    // 结束应用
    LOG_INFO(AC_Y("{} terminate"), app::name);
}
